﻿using System.Collections;
using Basic.FormCollect;
using Basic.FormModel.Column;
using Basic.FormModel.Form;
using Basic.FormModel.RecordItem;
using Basic.FormModel.UserRecord;
using Basic.FormRemoteModel;
using Basic.FormRemoteModel.QueryInter.Model;
using Basic.UserFormService.Interface;
using WeDonekRpc.Helper;

namespace Basic.UserFormService.lmpl
{
    internal class UserFormRecordService : IUserFormRecordService
    {
        private readonly IUserFormRecordCollect _Record;
        private readonly IUserFormItemCollect _RecordItem;
        private readonly ITableColumnCollect _Column;
        public UserFormRecordService ( IUserFormRecordCollect record,
            ITableColumnCollect column,
            IUserFormItemCollect recordItem )
        {
            this._Column = column;
            this._Record = record;
            this._RecordItem = recordItem;
        }
        public void LoadValues ( FormBase form, long lnkPk, string linkType, KeyValuePair<long, string>[] column, Dictionary<long, FormVal> vals )
        {
            UserRecord record = this._Record.Find(form.Id, linkType, lnkPk);
            if ( record == null || record.IsNull )
            {
                return;
            }
            long[] colId = column.ConvertAll(a => a.Key);
            RecordItem[] items = this._RecordItem.Finds<RecordItem>(record.Id, colId);
            if ( items.IsNull() )
            {
                return;
            }
            ColSet[] cols = this._Column.GetsColSet(colId);
            cols.ForEach(c =>
            {
                if ( c.TableType == FormTableType.单一表单 )
                {
                    RecordItem item = items.Find(a => a.ColumnId == c.Id);
                    FormVal val = this._Format(item, c);
                    vals.Add(c.Id, val);
                }
                else
                {
                    RecordItem[] list = items.FindAll(a => a.ColumnId == c.Id);
                    if ( list.IsNull() )
                    {
                        return;
                    }
                    FormVal val = this._Format(list, c);
                    vals.Add(c.Id, val);
                }
            });
        }

        private FormVal _Format ( RecordItem[] items, ColSet col )
        {
            FormVal val = new FormVal
            {
                DataType = FormRecordDataType.ListItem,
                IsNull = false,
                FuncType = col.FuncType,
            };
            if ( col.DataType == FormRecordDataType.Array )
            {
                val.ListItem = new FormListItem
                {
                    DataType = FormRecordDataType.Array,
                    Vals = items.OrderBy(a => a.RowIndex).Select(a => a.IsNull ? null : a.StrVal.SplitDel()).ToArray()
                };
                val.ListItem.Len = val.ListItem.Vals.Length;
            }
            else if ( col.DataType == FormRecordDataType.Long ||
                col.DataType == FormRecordDataType.DateTime ||
                col.DataType == FormRecordDataType.Date ||
                col.DataType == FormRecordDataType.Time )
            {
                val.ListItem = new FormListItem
                {
                    DataType = FormRecordDataType.Long,
                    LongVal = items.OrderBy(a => a.RowIndex).Select(a => a.LongVal).ToArray()
                };
                val.ListItem.Len = val.ListItem.LongVal.Length;
            }
            else if ( col.DataType == FormRecordDataType.Number )
            {
                val.ListItem = new FormListItem
                {
                    DataType = FormRecordDataType.Number,
                    NumVal = items.OrderBy(a => a.RowIndex).Select(a => a.NumVal).ToArray()
                };
                val.ListItem.Len = val.ListItem.NumVal.Length;
            }
            else if ( col.DataType == FormRecordDataType.Bool )
            {
                val.ListItem = new FormListItem
                {
                    DataType = FormRecordDataType.Bool,
                    BoolVal = items.OrderBy(a => a.RowIndex).Select(a => a.BoolVal).ToArray()
                };
                val.ListItem.Len = val.ListItem.BoolVal.Length;
            }
            else
            {
                string[] str = items.OrderBy(a => a.RowIndex).Select(a => a.StrVal).ToArray();
                val.ListItem = new FormListItem
                {
                    Len = str.Length,
                    DataType = FormRecordDataType.String,
                    StrVal = str
                };
            }
            if ( col.ControlSet.IsNotNull() )
            {
                Dictionary<string, object> obj = col.ControlSet.Json<Dictionary<string, object>>();
                if ( col.ColType == ControlType.Number && obj.TryGetValue("precision", out object v) )
                {
                    val.NumStep = Convert.ToInt32(v);
                }
                else if ( col.ColType == ControlType.Switch )
                {
                    if ( obj.TryGetValue("active-text", out v) )
                    {
                        val.ActivateText = Convert.ToString(v);
                    }
                    if ( obj.TryGetValue("inactive-text", out v) )
                    {
                        val.InactiveText = Convert.ToString(v);
                    }
                }
                else if ( col.FuncType == DataFuncType.选项值 && obj.TryGetValue("Items", out object it) && it != null )
                {
                    IList t = it as IList;
                    val.Items = new Dictionary<string, string>();
                    foreach ( IDictionary<string, object> i in t )
                    {
                        object k = i["value"];
                        val.Items.Add(Convert.ToString(i["text"]), k == null ? null : Convert.ToString(k));
                    }
                }
                else if ( ( col.FuncType == DataFuncType.字典项 || col.FuncType == DataFuncType.树形字典 ) && obj.TryGetValue("dicId", out it) && it != null )
                {
                    val.DicId = Convert.ToInt64(it);
                }
                else if ( col.FuncType == DataFuncType.上传的附件 && obj.TryGetValue("fileKey", out it) && it != null )
                {
                    val.DirKey = Convert.ToString(it);
                }
            }
            return val;
        }
        private FormVal _Format ( RecordItem item, ColSet col )
        {
            FormVal val = new FormVal
            {
                DataType = col.DataType,
                IsNull = item.IsNull,
                FuncType = col.FuncType
            };
            if ( item.IsNull )
            {
                return val;
            }
            if ( col.DataType == FormRecordDataType.Array )
            {
                val.IsNull = false;
                val.DataType = FormRecordDataType.Array;
                val.Vals = item.StrVal.Substring(1, item.StrVal.Length - 2).Split('|');
            }
            else
            {
                val.IsNull = false;
                val.StrVal = item.StrVal;
                val.DataType = col.DataType;
                val.NumVal = item.NumVal;
                val.LongVal = item.LongVal;
                val.BoolVal = item.BoolVal;
            }
            if ( col.ControlSet.IsNotNull() )
            {
                Dictionary<string, object> obj = col.ControlSet.Json<Dictionary<string, object>>();
                if ( col.ColType == ControlType.Number && obj.TryGetValue("precision", out object v) )
                {
                    val.NumStep = Convert.ToInt32(v);
                }
                else if ( col.ColType == ControlType.Switch )
                {
                    if ( obj.TryGetValue("active-text", out v) )
                    {
                        val.ActivateText = Convert.ToString(v);
                    }
                    if ( obj.TryGetValue("inactive-text", out v) )
                    {
                        val.InactiveText = Convert.ToString(v);
                    }
                }
                else if ( col.FuncType == DataFuncType.选项值 && obj.TryGetValue("Items", out object it) && it != null )
                {
                    IList t = it as IList;
                    val.Items = new Dictionary<string, string>();
                    foreach ( IDictionary<string, object> i in t )
                    {
                        object k = i["value"];
                        val.Items.Add(Convert.ToString(i["text"]), k == null ? null : Convert.ToString(k));
                    }
                }
                else if ( ( col.FuncType == DataFuncType.字典项 || col.FuncType == DataFuncType.树形字典 ) && obj.TryGetValue("dicId", out it) && it != null )
                {
                    val.DicId = Convert.ToInt64(it);
                }
                else if ( col.FuncType == DataFuncType.上传的附件 && obj.TryGetValue("fileKey", out it) && it != null )
                {
                    val.DirKey = Convert.ToString(it);
                }
            }
            return val;
        }
        public Dictionary<long, FormVal> GetValues ( FormBase form, FormValsGetArg arg )
        {
            Dictionary<long, FormVal> vals = new Dictionary<long, FormVal>();
            this.LoadValues(form, arg.LinkPK, arg.LinkType, arg.Column, vals);
            return vals;
        }
        public FormVal GetValue ( FormBase form, FormValGetArg arg )
        {
            FormVal val = new FormVal
            {
                IsNull = true
            };
            UserRecord record = this._Record.Find(form.Id, arg.LinkType, arg.LinkPK);
            if ( record == null || record.IsNull )
            {
                return val;
            }
            ColSet col = this._Column.GetColSet(arg.ColumnId);
            RecordItem[] item = this._RecordItem.Find<RecordItem>(record.Id, arg.ColumnId);
            if ( item.IsNull() )
            {
                return new FormVal
                {
                    DataType = col.DataType,
                    IsNull = true
                };
            }
            if ( col.TableType == FormTableType.单一表单 )
            {
                return this._Format(item[0], col);
            }
            return this._Format(item, col);
        }
    }
}
